﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using Moq;

namespace MvcWiki.Test.Repository.FileSystem.WikiPageFileSystemRepository
{
    public class DeleteEntityFacts
    {
        [Fact]
        public void Call()
        {
            var wikiPage = new MvcWiki.Model.WikiPage
            {
                Name = "Page",
                Namespace = new MvcWiki.Model.WikiNamespace { Name = "Namespace" }
            };

            var wikiNamespaceRepository = new Mock<MvcWiki.Repository.IWikiNamespaceRepository>();

            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            repositoryFactory.Setup(x => x.GetWikiNamespaceRepository()).Returns(wikiNamespaceRepository.Object);

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();
            fileSystem.Setup(x => x.GetDirectories("c:\\path", "Namespace---*"))
                .Returns(new string[] { "c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc" });
            fileSystem.Setup(x => x.GetDirectories("c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc", String.Format("*---{0}", wikiPage.Id)))
                .Returns(new string[] { "c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc\\Page---9f878f77-21bb-4fb1-a68e-3cd2c61201cc" });

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var wikiPageRepository = new MvcWiki.Repository.FileSystem.WikiPageFileSystemRepository(repositoryFactory.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            wikiPageRepository.DeleteEntity(wikiPage);
        }

        [Fact]
        public void Checks_Whether_Namespace_Directory_Exists()
        {
            var wikiPage = new MvcWiki.Model.WikiPage
            {
                Name = "Page",
                Namespace = new MvcWiki.Model.WikiNamespace { Name = "Namespace" }
            };

            var wikiNamespaceRepository = new Mock<MvcWiki.Repository.IWikiNamespaceRepository>();

            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            repositoryFactory.Setup(x => x.GetWikiNamespaceRepository()).Returns(wikiNamespaceRepository.Object);

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();
            fileSystem.Setup(x => x.GetDirectories("c:\\path", "Namespace---*"))
                .Returns(new string[] { "c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc" });
            fileSystem.Setup(x => x.GetDirectories("c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc", String.Format("*---{0}", wikiPage.Id)))
                .Returns(new string[] { "c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc\\Page---9f878f77-21bb-4fb1-a68e-3cd2c61201cc" });

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var wikiPageRepository = new MvcWiki.Repository.FileSystem.WikiPageFileSystemRepository(repositoryFactory.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            wikiPageRepository.DeleteEntity(wikiPage);

            fileSystem.VerifyAll();
        }

        [Fact]
        public void Throws_Exception_If_Namespace_Directory_Does_Not_Exist()
        {
            var wikiPage = new MvcWiki.Model.WikiPage
            {
                Name = "Page",
                Namespace = new MvcWiki.Model.WikiNamespace { Name = "Namespace" }
            };

            var wikiNamespaceRepository = new Mock<MvcWiki.Repository.IWikiNamespaceRepository>();

            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            repositoryFactory.Setup(x => x.GetWikiNamespaceRepository()).Returns(wikiNamespaceRepository.Object);

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();
            fileSystem.Setup(x => x.GetDirectories("c:\\path", "Namespace---*"))
                .Returns(new string[] { });

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var wikiPageRepository = new MvcWiki.Repository.FileSystem.WikiPageFileSystemRepository(repositoryFactory.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            Assert.Throws<MvcWiki.Exceptions.NamespaceDoesNotExistException>(
                () => wikiPageRepository.DeleteEntity(wikiPage));
        }

        [Fact]
        public void Checks_Whether_Page_Directory_Exists()
        {
            var wikiPage = new MvcWiki.Model.WikiPage
            {
                Name = "Page",
                Namespace = new MvcWiki.Model.WikiNamespace { Name = "Namespace" }
            };

            var wikiNamespaceRepository = new Mock<MvcWiki.Repository.IWikiNamespaceRepository>();

            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            repositoryFactory.Setup(x => x.GetWikiNamespaceRepository()).Returns(wikiNamespaceRepository.Object);

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();
            fileSystem.Setup(x => x.GetDirectories("c:\\path", "Namespace---*"))
                .Returns(new string[] { "c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc" });
            fileSystem.Setup(x => x.GetDirectories("c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc", String.Format("*---{0}", wikiPage.Id)))
                .Returns(new string[] { "c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc\\Page---9f878f77-21bb-4fb1-a68e-3cd2c61201cc" });

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var wikiPageRepository = new MvcWiki.Repository.FileSystem.WikiPageFileSystemRepository(repositoryFactory.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            wikiPageRepository.DeleteEntity(wikiPage);

            fileSystem.VerifyAll();
        }

        [Fact]
        public void Throws_Exception_If_Page_Directory_Does_Not_Exist()
        {
            var wikiPage = new MvcWiki.Model.WikiPage
            {
                Name = "Page",
                Namespace = new MvcWiki.Model.WikiNamespace { Name = "Namespace" }
            };

            var wikiNamespaceRepository = new Mock<MvcWiki.Repository.IWikiNamespaceRepository>();

            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            repositoryFactory.Setup(x => x.GetWikiNamespaceRepository()).Returns(wikiNamespaceRepository.Object);

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();
            fileSystem.Setup(x => x.GetDirectories("c:\\path", "Namespace---*"))
                .Returns(new string[] { "c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc" });
            fileSystem.Setup(x => x.GetDirectories("c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc", String.Format("*---{0}", wikiPage.Id)))
                .Returns(new string[] { });

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var wikiPageRepository = new MvcWiki.Repository.FileSystem.WikiPageFileSystemRepository(repositoryFactory.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            Assert.Throws<MvcWiki.Exceptions.PageDoesNotExistException>(
                () => wikiPageRepository.DeleteEntity(wikiPage));

            fileSystem.VerifyAll();
        }

        [Fact]
        public void Removes_Page_Directory()
        {
            var wikiPage = new MvcWiki.Model.WikiPage
            {
                Name = "Page",
                Namespace = new MvcWiki.Model.WikiNamespace { Name = "Namespace" }
            };

            var wikiNamespaceRepository = new Mock<MvcWiki.Repository.IWikiNamespaceRepository>();

            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            repositoryFactory.Setup(x => x.GetWikiNamespaceRepository()).Returns(wikiNamespaceRepository.Object);

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();
            fileSystem.Setup(x => x.GetDirectories("c:\\path", "Namespace---*"))
                .Returns(new string[] { "c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc" });
            fileSystem.Setup(x => x.GetDirectories("c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc", String.Format("*---{0}", wikiPage.Id)))
                .Returns(new string[] { "c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc\\Page---9f878f77-21bb-4fb1-a68e-3cd2c61201cc" });
            fileSystem.Setup(x => x.DeleteDirectory("c:\\path\\Namespace---9f878f77-21bb-4fb1-a68e-3cd2c61201cc\\Page---9f878f77-21bb-4fb1-a68e-3cd2c61201cc"));

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var wikiPageRepository = new MvcWiki.Repository.FileSystem.WikiPageFileSystemRepository(repositoryFactory.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            wikiPageRepository.DeleteEntity(wikiPage);

            fileSystem.VerifyAll();
        }
    }
}
